﻿using AlibabaCloud.OSS.V2.Models;
using OSS = AlibabaCloud.OSS.V2;

namespace WorkTool2.Helpers;

public static class AlibabaCloudOSSHelper
{
    public const string ACCESS_KEY_ID = "LTAI5tMx7rZjQKifgp4yox1d";
    public const string ACCESS_KEY_SECRET = "nx9QuJPUeIhl4MGwuspLXbLrwupLdq";
    public const string REGION = "cn-shenzhen";
    public const string BUCKET = "shu-tools";

    public static async Task<string> GetContext(string key)
    {
        // 加载OSS SDK的默认配置，此配置会自动从环境变量中读取凭证信息（如AccessKey）
        var cfg = OSS.Configuration.LoadDefault();
        // 创建静态凭证提供者，显式设置RAM账号密钥AccessKey ID和AccessKey Secret
        cfg.CredentialsProvider = new OSS.Credentials.StaticCredentialsProvider(ACCESS_KEY_ID, ACCESS_KEY_SECRET);
        // 设置配置的Bucket区域
        cfg.Region = REGION;

        // 使用配置信息创建OSS客户端实例
        using var client = new OSS.Client(cfg);

        // 若需一次性将内容全部读取到内存，可使用此重载方法
        var result = await client.GetObjectAsync(new OSS.Models.GetObjectRequest()
        {
            Bucket = BUCKET,
            Key = key,
        }, HttpCompletionOption.ResponseContentRead);

        // 获取响应的内容流
        using var body = result.Body;
        // 读取数据
        var reader = new StreamReader(body!);
        // 将流中的全部内容读取为字符串（内容加载到内存中）
        var data = reader.ReadToEnd();
        return data;
    }

    public static async Task Download(string key, string filePath)
    {
        // 加载OSS SDK的默认配置，此配置会自动从环境变量中读取凭证信息（如AccessKey）
        var cfg = OSS.Configuration.LoadDefault();
        // 创建静态凭证提供者，显式设置RAM账号密钥AccessKey ID和AccessKey Secret
        cfg.CredentialsProvider = new OSS.Credentials.StaticCredentialsProvider(ACCESS_KEY_ID, ACCESS_KEY_SECRET);
        // 设置配置的Bucket区域
        cfg.Region = REGION;

        // 使用配置信息创建OSS客户端实例
        using var client = new OSS.Client(cfg);
        try
        {
            Console.WriteLine("开始下载文件...");

            // 使用流式下载并显示进度
            var getRequest = new GetObjectRequest
            {
                Bucket = BUCKET,
                Key = key
            };

            var response = await client.GetObjectAsync(getRequest);
            using var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write);
            using var responseStream = response.Body;
            var buffer = new byte[81920]; // 80KB buffer
            long totalRead = 0;
            int bytesRead;

            var lastUpdateTime = DateTime.Now;
            var startTime = DateTime.Now;

            while ((bytesRead = await responseStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
            {
                await fileStream.WriteAsync(buffer.AsMemory(0, bytesRead));
                totalRead += bytesRead;

                // 每秒更新一次进度显示
                var currentTime = DateTime.Now;
                if ((currentTime - lastUpdateTime).TotalSeconds >= 1.0)
                {
                    var elapsedSeconds = (currentTime - startTime).TotalSeconds;
                    var speed = totalRead / elapsedSeconds / 1024; // KB/s

                    Console.WriteLine($"已下载: {FormatFileSize(totalRead)} | " +
                                    $"速度: {speed:F2} KB/s | " +
                                    $"耗时: {elapsedSeconds:F1}s");

                    lastUpdateTime = currentTime;
                }
            }

            var totalTime = (DateTime.Now - startTime).TotalSeconds;
            Console.WriteLine($"\n下载完成！");
            Console.WriteLine($"总大小: {FormatFileSize(totalRead)}");
            Console.WriteLine($"总耗时: {totalTime:F2}s");
            Console.WriteLine($"平均速度: {totalRead / totalTime / 1024:F2} KB/s");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"下载失败: {ex.Message}");
        }
    }

    private static string FormatFileSize(long bytes)
    {
        string[] sizes = { "B", "KB", "MB", "GB" };
        int order = 0;
        double len = bytes;

        while (len >= 1024 && order < sizes.Length - 1)
        {
            order++;
            len /= 1024;
        }

        return $"{len:0.##} {sizes[order]}";
    }
}